package com.audaque.springboot.foshanupload.web.webdemo.controller;

import com.audaque.springboot.foshanupload.log.anno.WebLogAnno;
import com.audaque.springboot.foshanupload.web.anno.RAnno;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;
import java.util.concurrent.*;

/**
 * @author zgb
 * @desc ...
 * @date 2023-07-03 18:53:47
 */
@Slf4j
@RestController
@RequestMapping("thread")
public class ThreadController {

    @RAnno
    @WebLogAnno
    @GetMapping("/threadId")
    public void threadId() throws Exception {
        long threadId = Thread.currentThread().getId();
        log.debug("threadId：" + threadId);
        Map<String, String> copyOfContextMap = MDC.getCopyOfContextMap();
        //runnable Lamda表达式
        new Thread(() -> {
            MDC.setContextMap(copyOfContextMap);
            log.debug("threadId：" + Thread.currentThread().getId());
        }).start();

    }

    @RAnno
    @WebLogAnno
    @GetMapping("/test}")
    public void test() throws Exception {

        //继承thread
        ExtendsThread extendsThread = new ExtendsThread();
        extendsThread.start();

        //实现runnable
        Thread runThread = new Thread(new AchieveRunnable());
        runThread.start();

        //调用callable 可以有返回值 可以捕获异常
        Callable<String> tc = new TestCallable();
        FutureTask<String> task = new FutureTask<String>(tc);
        new Thread(task).start();
        try {
            System.out.println(task.get());//获取返回值
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        //runable 匿名内部类方式
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("实现Runnable 匿名内部类方式：" + Thread.currentThread().getName());
            }
        }).start();

        //runnable Lamda表达式
        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("Lamda表达式:" + i);
            }
        }).start();

        System.out.println("主线程");

        //创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 5; i++) {
            AchieveRunnable achieveRunnable = new AchieveRunnable();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            executorService.execute(achieveRunnable);
        }
        //关闭线程池
        executorService.shutdown();
    }

    /**
     * 继承thread类
     */
    public static class ExtendsThread extends Thread {
        public void run() {
            System.out.println("方法一 继承Thread线程：" + Thread.currentThread().getName());
        }
    }

    /**
     * 实现runnable
     */
    public static class AchieveRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("方法二 实现Runnable：" + Thread.currentThread().getName());
        }
    }

    /**
     * 通过Callable和FutureTask创建线程
     */
    public static class TestCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            System.out.println("方法三 实现callable：" + Thread.currentThread().getName());
            return "我是callable的返回";
        }
    }


}
